package librpc

import (
	"io"
	"bytes"
	"kumachan/standalone/rpc"
	"kumachan/standalone/rpc/kmd"
	"kumachan/interpreter/runtime/def"
)


type RpcApiImpl struct {
	*KmdApiImpl
	ServiceIndex
}
type KmdApiImpl struct {
	context      *kmdTransformContext
	transformer  kmd.Transformer
}
type ServiceIndex (map[rpc.ServiceIdentifier] *def.RpcService)

func (impl *RpcApiImpl) LookupService(id rpc.ServiceIdentifier) (*def.RpcService, bool) {
	var service, exists = impl.ServiceIndex[id]
	return service, exists
}

func (impl *KmdApiImpl) GetTypeFromId(id kmd.TypeId) *kmd.Type {
	return impl.context.config.GetTypeFromId(id)
}
func (impl *KmdApiImpl) SerializeToStream(v Value, t *kmd.Type, stream io.Writer) error {
	var serializer = impl.transformer.Serializer
	var tv = KmdTypedValue {
		Type:  t,
		Value: v,
	}
	return kmd.Serialize(tv, serializer, stream)
}
func (impl *KmdApiImpl) DeserializeFromStream(t *kmd.Type, stream io.Reader) (Value, error) {
	var ts = impl.transformer
	var deserializer = ts.Deserializer
	obj, real_t, err := kmd.Deserialize(stream, deserializer)
	if err != nil { return nil, err }
	obj, err = ts.AssignObject(obj, real_t, t)
	if err != nil { return nil, err }
	return obj, nil
}
func (impl *KmdApiImpl) Serialize(v Value, t *kmd.Type) ([] byte, error) {
	var buf bytes.Buffer
	var err = impl.SerializeToStream(v, t, &buf)
	if err != nil { return nil, err }
	return buf.Bytes(), nil
}
func (impl *KmdApiImpl) Deserialize(binary ([] byte), t *kmd.Type) (Value, error) {
	var reader = bytes.NewReader(binary)
	return impl.DeserializeFromStream(t, reader)
}


